package com.itcast.util;

import com.alibaba.fastjson.*;
import org.aspectj.lang.*;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.*;
import org.springframework.core.annotation.*;
import org.springframework.stereotype.*;
import org.springframework.web.context.request.*;
import javax.servlet.http.*;
import java.lang.reflect.Method;
import java.util.*;

@Aspect
@Order(1)                               //设置切面的优先级：如果有多个切面，可通过设置优先级控制切面的执行顺序（数值越小，优先级越高）
@Component
public class QmttAspect {

    @Pointcut("execution(public String com.itcast.controller.*.*(..))")
    public void pointCutMethod() {
        
    }

//    // 声明环绕通知
//    @Around("pointCutMethod()")
//    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
//        Object ret = pjp.proceed();
//
//        try{
//            RequestAttributes ra = RequestContextHolder.getRequestAttributes();
//            ServletRequestAttributes sra = (ServletRequestAttributes) ra;
//            HttpServletRequest request = sra.getRequest();
//            Map reqMap=request.getParameterMap();
//            String uuid=(String)request.getAttribute("UUID");
//
//            System.out.println("Request UUID:"+uuid+"\t RequestBody:"+JSON.toJSONString(reqMap));
//
//            System.out.println("Response UUID:"+uuid+"\tResponseBody:"+JSON.toJSONString(ret));
//        }catch(Exception e){
//            e.printStackTrace();
//        }
//        return ret;
//    }

    @Before("pointCutMethod()")                                                                         //记录入参
    public void permissionCheck(JoinPoint point) {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes;
        HttpServletRequest request = servletRequestAttributes.getRequest();
        String UUID= (String) request.getAttribute("UUID");
        String reqBody=JSON.toJSONString(request.getParameterMap());
        System.out.println("UUID:"+UUID+"\t入参:"+reqBody);

//        System.out.println("@Before：模拟权限检查...");
//        System.out.println("@Before：目标方法为：" +
//                point.getSignature().getDeclaringTypeName() +
//                "." + point.getSignature().getName());
//        System.out.println("@Before：参数为：" + Arrays.toString(point.getArgs()));
//        System.out.println("@Before：被织入的目标对象为：" + point.getTarget());
    }


    @AfterReturning(pointcut="pointCutMethod()",returning="returnValue")                               //正常出参
    public void log(JoinPoint point, Object returnValue) {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes;
        HttpServletRequest request = servletRequestAttributes.getRequest();
        String UUID= (String) request.getAttribute("UUID");
        System.out.println("UUID:"+UUID+"\t出参:"+returnValue);


//        System.out.println("@AfterReturning：模拟日志记录功能...");
//        System.out.println("@AfterReturning：目标方法为：" +
//                point.getSignature().getDeclaringTypeName() +
//                "." + point.getSignature().getName());
//        System.out.println("@AfterReturning：参数为：" +
//                Arrays.toString(point.getArgs()));
//        System.out.println("@AfterReturning：返回值为：" + returnValue);
//        System.out.println("@AfterReturning：被织入的目标对象为：" + point.getTarget());

    }

//    @After("pointCutMethod()")
//    public void releaseResource(JoinPoint point) {
//        System.out.println("@After：模拟释放资源...");
//        System.out.println("@After：目标方法为：" +
//                point.getSignature().getDeclaringTypeName() +
//                "." + point.getSignature().getName());
//        System.out.println("@After：参数为：" + Arrays.toString(point.getArgs()));
//        System.out.println("@After：被织入的目标对象为：" + point.getTarget());
//    }

    /**
     * 在抛出异常时使用
     * @param joinPoint
     * @param ex
     */
    @AfterThrowing(value="pointCutMethod()",throwing = "ex")                                                                //异常出参
    public void afterThrowing(JoinPoint joinPoint, Throwable ex){//注解标注的方法抛出的异常)
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes;
        HttpServletRequest request = servletRequestAttributes.getRequest();
        String UUID= (String) request.getAttribute("UUID");
        System.out.println("UUID:"+UUID+"\t错误信息:"+ErrorUilts.saveErrorMessages(ex));
    }
}
